﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Dropthings.Widget.Widgets;
using Dropthings.Widget.Framework;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;

public partial class Widgets_VisifireWidget : System.Web.UI.UserControl, IWidget
{

    string strResult;      
    
    private IWidgetHost _Host;

    private XElement _State;
    private XElement State
    {
        get
        {
            string state = this._Host.GetState();
            if (string.IsNullOrEmpty(state))
                state = "<state><strPoshWidth>320</strPoshWidth><strPoshHeight>150</strPoshHeight><strChartType>Line</strChartType><strChartName>ChartName</strChartName><strXLabel>X label</strXLabel><strYLabel>Y Label</strYLabel><strPoshCode></strPoshCode><strHtmlRender>Empty</strHtmlRender><refresh>false</refresh></state>";
            if (_State == null) _State = XElement.Parse(state);
            return _State;
        }
    }

    public bool Refresh
    {
        get { return bool.Parse((State.Element("refresh") ?? new XElement("refresh", "false")).Value); }
        set
        {
            if (State.Element("refresh") != null) State.Element("refresh").Value = value.ToString();
            else State.Add(new XElement("refresh", value.ToString()));
        }
    }

    public string strPoshHeight
    {
        get { return (State.Element("strPoshHeight") ?? new XElement("strPoshHeight", "")).Value; }
        set { State.Element("strPoshHeight").Value = value; }
    }

    public string strPoshWidth
    {
        get { return (State.Element("strPoshWidth") ?? new XElement("strPoshWidth", "")).Value; }
        set { State.Element("strPoshWidth").Value = value; }
    }

    public string strChartName
    {
        get { return (State.Element("strChartName") ?? new XElement("strChartName", "")).Value; }
        set { State.Element("strChartName").Value = value; }
    }

    public string strXLabel
    {
        get { return (State.Element("strXLabel") ?? new XElement("strXLabel", "")).Value; }
        set { State.Element("strXLabel").Value = value; }
    }

    public string strYLabel
    {
        get { return (State.Element("strYLabel") ?? new XElement("strYLabel", "")).Value; }
        set { State.Element("strYLabel").Value = value; }
    }

    public string strChartType
    {
        get { return (State.Element("strChartType") ?? new XElement("strChartType", "")).Value; }
        set { State.Element("strChartType").Value = value; }
    }

    public string strPoshCode
    {
        get { return (State.Element("strPoshCode") ?? new XElement("strPoshCode", "")).Value; }
        set { State.Element("strPoshCode").Value = value; }
    }

    public string strHtmlRender
    {
        get { return (State.Element("strHtmlRender") ?? new XElement("strHtmlRender", "")).Value; }
        set { State.Element("strHtmlRender").Value = value; }
    }
    
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["Refresher"] != null)
        {
            string strTraceSession = Session["Refresher"].ToString();
            string[] strSplittedArgs = strTraceSession.Split(';');
            strPoshCode = strPoshCode.Replace(strSplittedArgs[0], strSplittedArgs[1]);
            this.executePowerShellCode(strPoshCode);
            this.strHtmlRender = strResult;
        }
        
        else if (Request.Params["Refresh"] == "yes")
        {
            this.executePowerShellCode(strPoshCode);
            this.strHtmlRender = strResult;
            this.State.Add(new XCData(strResult));
            this.SaveState();
        }
   
    }

    void IWidget.Init(IWidgetHost host)
    {
        this._Host = host;
    }

    void IWidget.ShowSettings()
    {
        PoshtextBox.Text = this.strPoshCode;
        PoshWidth.Text = this.strPoshWidth;
        PoshHeight.Text = this.strPoshHeight;        
        ddlChartType.SelectedValue = this.strChartType;        
        ChartName.Text = this.strChartName;
        xLabel.Text = this.strXLabel;
        yLabel.Text = this.strYLabel;
        SettingsPanel.Visible = true;        
    }
    void IWidget.HideSettings()
    {
        SettingsPanel.Visible = false;
        Page.Response.Redirect(Page.Request.Url.ToString(), true);
    }
    void IWidget.Minimized()
    {
    }
    void IWidget.Maximized()
    {
    }
    void IWidget.Closed()
    {
    }


    protected void executePowerShellCode(string code)
    {
        // On The Fly PowerShell script modification with GUI informations
        
        StringWriter writer = new StringWriter();
        Server.HtmlDecode(code, writer);
        StreamReader objReader = new StreamReader(Server.MapPath("~/PowerShell/visifire.ps1"));
        string strContent = objReader.ReadToEnd();        
        string targetWidth = this.strPoshWidth;
        string targetHeigth = this.strPoshHeight;
        string chartType = this.strChartType;
        string chartName = this.strChartName;
        string xLabel = this.strXLabel;
        string yLabel = this.strYLabel;

        strContent = strContent.Replace("@width@", targetWidth);
        strContent = strContent.Replace("@heigth@", targetHeigth);
        strContent = strContent.Replace("@type@", chartType);
        strContent = strContent.Replace("@ChartName@", chartName);
        strContent = strContent.Replace("@xLabel@", xLabel);
        strContent = strContent.Replace("@yLabel@", yLabel);
        objReader.Close();
        
        string strPoshCode = strContent + writer.ToString();
        
        // create Powershell runspace
        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
        Pipeline pipeline = runspace.CreatePipeline();
        pipeline.Commands.AddScript(strPoshCode);
        pipeline.Commands.Add("Out-String");

        Collection<PSObject> results = null;
        string strError = null;
        try
        {
            results = pipeline.Invoke();
        }
        catch (RuntimeException e)
        {
            // Display a message and exit if a RuntimeException is thrown
            strError = e.GetType().Name + ": " + e.Message;
        }
        runspace.Close();

        if (strError != null)
        {
            strResult = strError;
        }
        else
        {
            // convert the script result into a single string
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PSObject obj in results)
            {
                stringBuilder.AppendLine(obj.ToString());
            }
            strResult = stringBuilder.ToString();
        }        
    }

    private void SaveState()
    {
        var xml = this.State.Xml();
        this._Host.SaveState(xml);
    }

    protected void SaveSettings_Clicked(object sender, EventArgs e)
    {
        string renderHeight = PoshHeight.Text;
        string renderWidth = PoshWidth.Text;
        string renderType = ddlChartType.SelectedItem.Text;
        string renderName = ChartName.Text;
        string renderXLabel = xLabel.Text;
        string renderYLabel = yLabel.Text;

        this.strPoshHeight = renderHeight;
        this.strPoshWidth = renderWidth;
        this.strChartType = renderType;
        this.strChartName = renderName;
        this.strXLabel = renderXLabel;
        this.strYLabel = renderYLabel;
        
        string PoshCode = PoshtextBox.Text;
        this.strPoshCode = PoshCode;
        if (PoshCode != null)
        {
            this.executePowerShellCode(PoshCode);
        }
        this.strHtmlRender = strResult;
        this.State.Add(new XCData(strResult));

        

        this.SaveState();        
        Page.Response.Redirect(Page.Request.Url.ToString(), true);      
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        if (strHtmlRender != null)
        {
            this.Output.Text = this.strHtmlRender;
        }        
    }

}
